/*
 * date: 2009-11-23 
 * author: Maciej Smolenski <jezdnia@gmail.com>
 */
#include <signal.h>
#include <sys/signalfd.h>
#include <iostream>
#include "rpc_monitor.hpp"
#include "log.hpp"
#include "config.hpp"

#define LOG_IDENT "rpcm_dump"

namespace rm=rpc_monitor;
rm::rpc_monitor_service<boost::interprocess::open_only_t> monitor(SHARE_MONITOR_NAME, MONITOR_MUTEX_NAME);

bool finish = false;

void finish_handler(int signum, siginfo_t *sig_info, void *context)
{
	finish = true;
}

struct msg_exception{
	std::string m_msg;
	msg_exception(const std::string &p_msg) : m_msg(p_msg) {}
	msg_exception(const char *p_msg) : m_msg(p_msg) {}
};

void dump_monitor()
{
	rm::stdset set;
	if (monitor.get_services(set)==result_failure)
		throw msg_exception("get services failed");

	for(rm::stdset::const_iterator it = set.begin(); it!=set.end(); it++)
		std::cout << *it << std::endl;

	std::cout << std::endl;
}

int main(int argc, char *argv[])
{
	openlog(LOG_IDENT, SYSLOG_OPTION, SYSLOG_FACILITY);

	sigset_t mask_info;
	if (sigemptyset(&mask_info)==-1)
		SYSLOG_RETURN(1, "sigemptyset %m");
	if (sigaddset(&mask_info, SIGUSR1))
		SYSLOG_RETURN(1, "sigaddset %m");
	if (sigprocmask(SIG_BLOCK, &mask_info, NULL)==-1)
		SYSLOG_RETURN(1, "sigprocmask %m");

	int sig_fd;
       	if ((sig_fd = signalfd(-1, &mask_info, 0)) == -1)
		SYSLOG_RETURN(1, "signalfd %m");

	sigset_t mask;
	if (sigemptyset(&mask)==-1)
		SYSLOG_RETURN(1, "sigemptyset %m");

	struct sigaction finish_action;
	finish_action.sa_sigaction = finish_handler;
       	finish_action.sa_mask = mask;
	finish_action.sa_flags = SA_SIGINFO;

	if (sigaction(SIGINT, &finish_action, NULL)==-1)
		SYSLOG_RETURN(1, "sigaction %m");

	while(!finish)
	{
		try{
		dump_monitor();
		}
		catch(msg_exception &e) { std::cerr << e.m_msg << std::endl; }

		while (true)
		{
			struct signalfd_siginfo info;
			ssize_t s = read(sig_fd, &info, sizeof(info));
			if (s==-1)
			{
				if (errno==EINTR)
					break;
				else
					SYSLOG_RETURN(1, "read %m");
			}
			else if (s<sizeof(info))
				SYSLOG_ERR("read (signalfd_siginfo)");
			else if (info.ssi_signo == SIGUSR1)
				break;
		}
	}

	closelog();
	return 0;
}

